package net.xdclass.controller;

import lombok.extern.slf4j.Slf4j;
import net.xdclass.enums.ShortLinkStateEnum;
import net.xdclass.model.vo.ShortLinkVO;
import net.xdclass.service.IShortLinkService;
import net.xdclass.util.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@Slf4j
public class LinkApiController {
    @Autowired
    private IShortLinkService shortLinkService;
    /**
     * 解析 301还是302，这边是返回http code是302
     * <p>
     * 知识点⼀，为什么要⽤ 301 跳转⽽不是 302 呐？
     * <p>
     * 301 是永久重定向，302 是临时重定向。
     * <p>
     * 短地址⼀经⽣成就不会变化，所以⽤ 301 是同时对服务器压
     ⼒也会有⼀定减少
     * <p>
     * 但是如果使⽤了 301，⽆法统计到短地址被点击的次数。
     * <p>
     * 所以选择302虽然会增加服务器压⼒，但是有很多数据可以获
     取进⾏分析
     *
     * @param linkCode
     * @return
     */

    /**
     * 短链跳转
     */
    @GetMapping(path = "/{shortLinkCode}")
    public void dispatch(@PathVariable(name = "shortLinkCode") String shortLinkCode
            , HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        try {
            log.info("短链跳转，短链编码：{}", shortLinkCode);
            //判断短链码是否违规
            if (!isLetterDigit(shortLinkCode)) {
                log.error("短链跳转，短链编码：{}，违规", shortLinkCode);
                return;
            }
            ShortLinkVO shortLinkVO = shortLinkService.parseShortLinkCode(shortLinkCode);
            if (isVisitable(shortLinkVO)) {
                String removeUrlPrefix = CommonUtil.removeUrlPrefix(shortLinkVO.getOriginalUrl());
                shortLinkVO.setOriginalUrl(removeUrlPrefix);
                httpServletResponse.setHeader("Location", shortLinkVO.getOriginalUrl());
                httpServletResponse.setStatus(HttpStatus.FOUND.value());
            } else {
                httpServletResponse.setStatus(HttpStatus.NOT_FOUND.value());
                return;
            }
        } catch (Exception e) {
            httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }

    }

    /**
     * 判断字符串是否只包含字母和数字
     *
     * @param str
     * @return
     */
    private static boolean isLetterDigit(String str) {
        return str.matches("^[a-zA-Z0-9]+$");
    }

    /**
     * 判断短链是否可用
     *
     * @param shortLinkVO
     * @return
     */
    private static boolean isVisitable(ShortLinkVO shortLinkVO) {
        if (shortLinkVO.getExpired().getTime() == -1) {
            return true;
        }
        if (shortLinkVO.getExpired().getTime() > CommonUtil.getCurrentTimestamp())
            if (shortLinkVO != null) {
                if (ShortLinkStateEnum.ACTIVE.name().equalsIgnoreCase(shortLinkVO.getState())) {
                    return true;
                }
            }
        return false;
    }
}
